#phi_n = image_n - avg
#need to find u_n orthonormal maximizing lambda_k = (1/M)sum_{m=1}^M (u_k^T*phi_m)^2
# maximizing the average dot product with all of the images

#equivalently
# let L_m,n = phi_m^T * phi_n
# then find eigenvectors of L (the v's)
# then we have the eigenfaces u_n = sum_m=1^M (v_l)_k*phi_k

#get the k eigenvectors with largest eigenvalues in the matrix A (possibly more if many matching eigenvalues, but unlikely)
getEigenVect <- function(A,k) {
  ev <- eigen(A)
  thresh <- sort(ev$values,decreasing=TRUE)[k]
  t(ev$vectors[,ev$values >= thresh])
}

#given a learner and a parameter for that learner, returns a learner parameterized off of number of eigenvectors
getEigenLearner <- function(param,learn) {function(trnx,trny,eigenCount) {
  e <- getEigenVect(trnx%*%t(trnx),eigenCount)
  projX <- apply(trnx,2,project,e)
  model <- learn(projX,trny,param)
  model$eigenVecs <- e
  return(model)
}}

getEigenPredicter <- function(param,predict) {function(testx,model) {
  #NOTE: do we still want to project it? the predicter seems to be taking care of projection already
  predict(project(testx,model$eigenVecs),model)
}}



